package com.chixing.service.impl;

import com.chixing.mapper.CarMapper;
import com.chixing.mapper.MyOrderMapper;
import com.chixing.mapper.StoreCarMapper;
import com.chixing.mapper.StoreMapper;
import com.chixing.pojo.*;
import com.chixing.service.CarService;
import com.chixing.util.DateUtil;
import com.chixing.util.ServerResponse;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
public class CarServiceImpl implements CarService {
    @Autowired
    private CarMapper carMapper;
    @Autowired
    private StoreCarMapper storeCarMapper;
    @Autowired
    private StoreMapper storeMapper;
    @Autowired
    private MyOrderMapper myOrderMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Override
    public ServerResponse getAll() {
        return ServerResponse.getSuccess(carMapper.selectByExample(null));
    }

    @Override
    public ServerResponse getCarDetail(Integer carId) {
        Car car = carMapper.selectByPrimaryKey(carId);
        if (car!=null)
            return ServerResponse.getSuccess(car);
        return ServerResponse.getFail(null);
    }

    // 多条件动态查询
    @Override
    public ServerResponse getCarByContain(String carType,
                                          String carBrand,
                                          Float minCarDailyPrice,
                                          Float maxCarDailyPrice,
                                          String carShiftType,
                                          Integer carSeatNumber,
                                          String orderBy,
                                          Integer pageNum) {
        CarExample carExample = new CarExample();
        if(orderBy.equals("-1"))
            orderBy = null;
        if(carType.equals("-1"))
            carType = null;
        if(carBrand.equals("-1"))
            carBrand = null;

        if(minCarDailyPrice == -1)
            minCarDailyPrice = null;

        if(maxCarDailyPrice == -1)
            maxCarDailyPrice = null;

        if(carShiftType.equals("-1"))
            carShiftType = null;

        if(carSeatNumber == -1)
            carSeatNumber = null;


        if(orderBy != null)
            carExample.setOrderByClause(orderBy);
        CarExample.Criteria criteria = carExample.createCriteria();
        if(carType != null)
            criteria.andCarTypeEqualTo(carType);
        if(carBrand != null)
            criteria.andCarBrandEqualTo(carBrand);
        if(minCarDailyPrice != null)
            criteria.andCarDailyPriceGreaterThanOrEqualTo(minCarDailyPrice);
        if(maxCarDailyPrice != null)
            criteria.andCarDailyPriceLessThanOrEqualTo(maxCarDailyPrice);
        if(carShiftType != null)
            criteria.andCarShiftTypeEqualTo(carShiftType);
        if(carSeatNumber != null)
            criteria.andCarSeatNumberEqualTo(carSeatNumber);
        PageHelper.startPage(pageNum,3);
        List<Car> carList = carMapper.selectByExample(carExample);
        PageInfo<Car> carPageInfo = new PageInfo<>(carList);
        if(carList.size() > 0 )
            return ServerResponse.getSuccess(carPageInfo);
        return ServerResponse.getFail(null);
    }

    @Override
    public ServerResponse getHotCarToIndex() {
        ValueOperations valueOperations = redisTemplate.opsForValue();

        StoreCarExample storeCarExample = new StoreCarExample();
        storeCarExample.createCriteria().andStatusEqualTo(0);
        storeCarExample.setOrderByClause("car_sale_count desc");
        List<StoreCar> storeCarList;
        String key = "carStoreListIndexData";
        if(valueOperations.getOperations().hasKey(key)){
            storeCarList = (List)valueOperations.get(key);
        }else{
            storeCarList = storeCarMapper.selectByExample(storeCarExample);
            valueOperations.set(key,storeCarList,3,TimeUnit.MINUTES);
        }
        List<Car> carList;
        String carKey = "carListIndexData";
        if(valueOperations.getOperations().hasKey(carKey)){
            carList = (List)valueOperations.get(carKey);
        }else{
            carList = new ArrayList<>();
            for(StoreCar storeCar: storeCarList){
                Car car = carMapper.selectByPrimaryKey(storeCar.getCarId());
                if(!carList.contains(car))
                    carList.add(car);
                if(carList.size() == 4)
                    break;
            }
            valueOperations.set(carKey,carList,3, TimeUnit.MINUTES);
        }

        if(carList.size() > 0)
            return ServerResponse.getSuccess(carList);
        return ServerResponse.getFail(null);
    }

    @Override
    public ServerResponse getStoreByCarIdAndStoreCity(Integer carId, String storeArea) {
        StoreCarExample storeCarExample = new StoreCarExample();
        storeCarExample.createCriteria().andCarIdEqualTo(carId).andStatusEqualTo(0);
        List<StoreCar> storeCarList = storeCarMapper.selectByExample(storeCarExample);
        List<Store> storeList = new ArrayList<>();
        for(StoreCar storeCar : storeCarList){
            StoreExample storeExample = new StoreExample();
            storeExample.createCriteria().andStoreIdEqualTo(storeCar.getStoreId()).andStoreAreaEqualTo(storeArea);
            List<Store> storeList1 = storeMapper.selectByExample(storeExample);
            if(storeList1.size() > 0 )
                storeList.add(storeList1.get(0));
        }
        if(storeList.size()>0) {
            System.out.println("hello");
            return ServerResponse.getSuccess(storeList);
        }
        return ServerResponse.getFail(null);
    }


    public ServerResponse getStoreByCarIdAndStoreArea(Integer carId,String storeArea){
        StoreCarExample storeCarExample = new StoreCarExample();
        storeCarExample.createCriteria().andCarIdEqualTo(carId);
        List<StoreCar> storeCarList = storeCarMapper.selectByExample(storeCarExample);
        List<Store> storeList = new ArrayList<>();
        for(StoreCar storeCar : storeCarList){
            StoreExample storeExample = new StoreExample();
            StoreExample.Criteria storeExampleCriteria = storeExample.createCriteria();
            storeExampleCriteria.andStoreIdEqualTo(storeCar.getStoreId());
            if(!storeArea.equals("-1")) {
                storeExampleCriteria.andStoreAreaEqualTo(storeArea);
            }
            List<Store> storeList1 = storeMapper.selectByExample(storeExample);
            if(storeList1.size()>0)
                storeList.add(storeList1.get(0));
        }
        if(storeList.size()>0)
            return ServerResponse.getSuccess(storeList);
        return ServerResponse.getFail(null);
    }

    @Override
    @Cacheable(key = "#storeId+'-'+#getCarTime+'-'+#carType+'-'+#carBrand+'-'+#minCarDailyPrice+'-'+#maxCarDailyPrice+'-'+#carShiftType+'-'+#carSeatNumber+'-'+#orderBy+'-'+#pageNum",cacheNames = {"carList"})
    public ServerResponse getCarByContainAndDate(Integer storeId, Date getCarTime, String carType, String carBrand, Float minCarDailyPrice, Float maxCarDailyPrice, String carShiftType, Integer carSeatNumber, String orderBy, Integer pageNum) {
        if(pageNum == null)
            pageNum = 1;
        if(carType == null || carType.equals("-1"))
            carType = null;
        if(carBrand == null || carBrand.equals("-1"))
            carBrand = null;

        if(minCarDailyPrice == null || minCarDailyPrice == -1)
            minCarDailyPrice = null;

        if(maxCarDailyPrice == null || maxCarDailyPrice == -1)
            maxCarDailyPrice = null;

        if(carShiftType == null || carShiftType.equals("-1"))
            carShiftType = null;

        if(carSeatNumber == null || carSeatNumber == -1)
            carSeatNumber = null;
        PageHelper.startPage(pageNum,5);
        List<Car> carList = carMapper.selectByContainAndStoreAntReturnCarTime(storeId,getCarTime,carType,carBrand,minCarDailyPrice,maxCarDailyPrice,carShiftType,carSeatNumber);
        if(orderBy != null && !orderBy.equals("-1")){
            switch (orderBy) {
                case "car_daily_price desc":
                    carList.sort(new Comparator<Car>() {
                        @Override
                        public int compare(Car o1, Car o2) {
                            return o2.getCarDailyPrice().compareTo(o1.getCarDailyPrice());
                        }
                    });
                    break;
                case "car_daily_price asc":
                    carList.sort(new Comparator<Car>() {
                        @Override
                        public int compare(Car o1, Car o2) {
                            return o1.getCarDailyPrice().compareTo(o2.getCarDailyPrice());
                        }
                    });
                    break;
                case "car_displacement desc":
                    carList.sort(new Comparator<Car>() {
                        @Override
                        public int compare(Car o1, Car o2) {
                            return o2.getCarDisplacement().compareTo(o1.getCarDisplacement());
                        }
                    });
                    break;
                case "car_displacement asc":
                    carList.sort(new Comparator<Car>() {
                        @Override
                        public int compare(Car o1, Car o2) {
                            return o1.getCarDisplacement().compareTo(o2.getCarDisplacement());
                        }
                    });
                    break;
            }
        }

        PageInfo<Car> carPageInfo = new PageInfo<>(carList);
        ServerResponse serverResponse = ServerResponse.getSuccess(carPageInfo);
        String carListId =storeId+'-'+ DateUtil.dateToString(getCarTime,DateUtil.DATE_PATTEN_YMDHM) +'-'+carType+'-'+carBrand+'-'+minCarDailyPrice+'-'+maxCarDailyPrice+'-'+carShiftType+'-'+carSeatNumber+'-'+orderBy+'-'+pageNum;

        redisTemplate.opsForValue().set(carListId,serverResponse,10,TimeUnit.MINUTES);
        if(carList.size()>0)
            return serverResponse;
        return ServerResponse.getFail(null);
    }

    @Override
    public Car getById(Integer carId) {
        return carMapper.selectByPrimaryKey(carId);
    }
}
